﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using l1cs.server.model.Instance;
using l1cs.server.templates;
using l1cs.server.model;
using l1cs.server.serverpackets;
using l1cs.server.datatables;

namespace l1cs.server.clientpackets
{
    public class C_GiveItem : ClientBasePacket
    {
        private static Logger _log = Logger.getLogger( typeof( C_GiveItem ).FullName );
        private const String _C_GIVE_ITEM = "[C] C_GiveItem";

        private static Random _random = new Random();

        public C_GiveItem( byte[] decrypt, ClientThread client )
            : base( decrypt )
        {
            int targetId = readD();
            int x = readH();
            int y = readH();
            int itemId = readD();
            int count = readD();

            L1PcInstance pc = client.getActiveChar();
            if ( pc.isGhost() )
            {
                return;
            }

            L1Object l1object = L1World.getInstance().findObject( targetId );
            if ( l1object == null || !( l1object is L1NpcInstance ) )
            {
                return;
            }
            L1NpcInstance target = (L1NpcInstance)l1object;
            if ( !isNpcItemReceivable( target.getNpcTemplate() ) )
            {
                return;
            }
            L1Inventory targetInv = target.getInventory();

            L1Inventory inv = pc.getInventory();
            L1ItemInstance item = inv.getItem( itemId );
            if ( item == null )
            {
                return;
            }
            if ( item.isEquipped() )
            {
                pc.sendPackets( new S_ServerMessage( 141 ) ); // \f1装備しているものは、人に渡すことができません。
                return;
            }
            if ( !item.getItem().isTradable() )
            {
                pc.sendPackets( new S_ServerMessage( 210, item.getItem().getName() ) ); // \f1%0は捨てたりまたは他人に讓ることができません。
                return;
            }
            if ( item.getBless() >= 128 )
            { // 封印された装備
                // \f1%0は捨てたりまたは他人に讓ることができません。
                pc.sendPackets( new S_ServerMessage( 210, item.getItem().getName() ) );
                return;
            }
            foreach ( Object petObject in pc.getPetList().Values )
            {
                if ( petObject is L1PetInstance )
                {
                    L1PetInstance pet = (L1PetInstance)petObject;
                    if ( item.getId() == pet.getItemObjId() )
                    {
                        // \f1%0は捨てたりまたは他人に讓ることができません。
                        pc.sendPackets( new S_ServerMessage( 210, item.getItem().getName() ) );
                        return;
                    }
                }
            }
            if ( targetInv.checkAddItem( item, count ) != L1Inventory.OK )
            {
                pc.sendPackets( new S_ServerMessage( 942 ) ); // 相手のアイテムが重すぎるため、これ以上あげられません。
                return;
            }
            item = inv.tradeItem( item, count, targetInv );
            target.onGetItem( item );
            target.turnOnOffLight();
            pc.turnOnOffLight();

            L1PetType petType = PetTypeTable.getInstance().get( target.getNpcTemplate().get_npcId() );
            if ( petType == null || target.isDead() )
            {
                return;
            }

            if ( item.getItemId() == petType.getItemIdForTaming() )
            {
                tamePet( pc, target );
            }
            if ( item.getItemId() == 40070 && petType.canEvolve() )
            {
                evolvePet( pc, target );
            }
        }

        private static String[] receivableImpls = new String[] { "L1Npc", // NPC
			"L1Monster", // モンスター
			"L1Guardian", // エルフの森の守護者
			"L1Teleporter", // テレポーター
			"L1Guard" }; // ガード

        private bool isNpcItemReceivable( L1Npc npc )
        {
            foreach ( String impl in receivableImpls )
            {
                if ( npc.getImpl().Equals( impl ) )
                {
                    return true;
                }
            }
            return false;
        }

        private void tamePet( L1PcInstance pc, L1NpcInstance target )
        {
            if ( target is L1PetInstance
                    || target is L1SummonInstance )
            {
                return;
            }

            int petcost = 0;
            //Object[] petlist = pc.getPetList().values().toArray();
            foreach ( L1NpcInstance pet in pc.getPetList().Values )
            {
                petcost += pet.getPetcost();
            }
            int charisma = pc.getCha();
            if ( pc.isCrown() )
            { // 君主
                charisma += 6;
            }
            else if ( pc.isElf() )
            { // エルフ
                charisma += 12;
            }
            else if ( pc.isWizard() )
            { // WIZ
                charisma += 6;
            }
            else if ( pc.isDarkelf() )
            { // DE
                charisma += 6;
            }
            else if ( pc.isDragonKnight() )
            { // ドラゴンナイト
                charisma += 6;
            }
            else if ( pc.isIllusionist() )
            { // イリュージョニスト
                charisma += 6;
            }
            charisma -= petcost;

            L1PcInventory inv = pc.getInventory();
            if ( charisma >= 6 && inv.getSize() < 180 )
            {
                if ( isTamePet( target ) )
                {
                    L1ItemInstance petamu = inv.storeItem( 40314, 1 ); // ペットのアミュレット
                    if ( petamu != null )
                    {
                        new L1PetInstance( target, pc, petamu.getId() );
                        pc.sendPackets( new S_ItemName( petamu ) );
                    }
                }
                else
                {
                    pc.sendPackets( new S_ServerMessage( 324 ) ); // てなずけるのに失敗しました。
                }
            }
        }

        private void evolvePet( L1PcInstance pc, L1NpcInstance target )
        {
            if ( !( target is L1PetInstance ) )
            {
                return;
            }
            L1PcInventory inv = pc.getInventory();
            L1PetInstance pet = (L1PetInstance)target;
            L1ItemInstance petamu = inv.getItem( pet.getItemObjId() );
            if ( pet.getLevel() >= 30 && // Lv30以上
                    pc == pet.getMaster() && // 自分のペット
                    petamu != null )
            {
                L1ItemInstance highpetamu = inv.storeItem( 40316, 1 );
                if ( highpetamu != null )
                {
                    pet.evolvePet( highpetamu.getId() );// 進化させる
                    pc.sendPackets( new S_ItemName( highpetamu ) );
                    inv.removeItem( petamu, 1 );
                }
            }
        }

        private bool isTamePet( L1NpcInstance npc )
        {
            bool isSuccess = false;
            int npcId = npc.getNpcTemplate().get_npcId();
            if ( npcId == 45313 )
            { // タイガー
                if ( npc.getMaxHp() / 3 > npc.getCurrentHp() // HPが1/3未満で1/16の確率
                        && _random.Next( 16 ) == 15 )
                {
                    isSuccess = true;
                }
            }
            else
            {
                if ( npc.getMaxHp() / 3 > npc.getCurrentHp() )
                {
                    isSuccess = true;
                }
            }

            if ( npcId == 45313 || npcId == 45044 || npcId == 45711 )
            { // タイガー、ラクーン、紀州犬の子犬
                if ( npc.isResurrect() )
                { // RES後はテイム不可
                    isSuccess = false;
                }
            }

            return isSuccess;
        }

        override
        public String getType()
        {
            return _C_GIVE_ITEM;
        }
    }
}